from uuid import UUID
from typing import Optional

from django.db import models
from uuid_extensions import uuid7

from .fields import OptimizedUUIDField


__all__ = [
    'OptimizedUUIDModel',
    'convert_to_uuid',
]


def convert_to_uuid(value: str) -> Optional[UUID]:
    """
    uuid字符串转UUID对象
    :return:
        UUID()  # success
        None  # fail, uuid无效
    """
    if isinstance(value, UUID):
        return value

    try:
        return UUID(value)
    except ValueError as e:
        return None


class OptimizedUUIDModel(models.Model):
    id = OptimizedUUIDField(blank=True, editable=False, primary_key=True, verbose_name='ID')

    class Meta:
        abstract = True

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        self.enforce_id()
        super().save(force_insert=force_insert, force_update=force_update,
                     using=using, update_fields=update_fields)

    def enforce_id(self):
        """确保id有效"""
        if not self.id:
            self.id = self.generate_id()

        return self.id

    @staticmethod
    def generate_id() -> UUID:
        return uuid7()
